package com.sghd.football.module.game.service.core;

import com.sghd.common.utils.model.RatioProbability;
import com.sghd.football.module.game.service.config.model.ConfigRoom;

import java.util.*;

/**
 * 10个普通元素+3个特殊元素
 */
public enum ChessType {
    /**射门*/
    CT_SHOOT_0,
    /**守门员*/
    CT_GOALIE_1,
    /**木偶人*/
    CT_PUPPET_2,
    /**红马*/
    CT_REDHORSE_3,
    /**城堡*/
    CT_CASTLE_4,
    /**球鞋*/
    CT_SHOES_5,
    CT_J_6,
    CT_Q_7,
    CT_K_8,
    CT_A_9,
    CT_WILD,
    CT_BONUS(true),
    CT_SCATTER(true);
    private int limit;//最少连续出现个数
    private Set<ChessType> all = new HashSet<>();

    private ChessType(boolean special) {
        this.special = special;
    }

    private ChessType() {
    }

    private boolean special = false;
    private Map<Integer, Integer> count2Rate = new HashMap<>();
    /**<房间id, 元素出现权重>*/
    private static Map<Integer, RatioProbability<ChessType>> normalRatioForRoom = new HashMap<>();//普通旋转时各元素出现权重
    private static Map<Integer, RatioProbability<ChessType>> freeRatioForRoom = new HashMap<>();//免费旋转时各元素出现权重

    static {
        //CT_WILD 特殊元素包含除BONUD, SCATTER外的所有元素
        for (ChessType type : ChessType.values()) {
            if (type.equals(CT_BONUS) || type.equals(CT_SCATTER)) {
                continue;
            }
            CT_WILD.all.add(type);
        }
    }

    public boolean isSpecial() {
        return special;
    }

    public static void init(Collection<ConfigRoom> configRooms) {
        for (ConfigRoom configRoom : configRooms) {
            //普通旋转元素出现概率
            Integer[] rates = configRoom.getRates();
            Map<ChessType, Integer> ratio = new HashMap<>();
            for (int i = 0; i < rates.length; i++) {
                ratio.put(ChessType.values()[i], rates[i]);
            }
            normalRatioForRoom.put(configRoom.getId(), RatioProbability.valueOf(ratio));
            //免费旋转元素出现概率
            rates = configRoom.getRatesFree();
            ratio = new HashMap<>();
            for (int i = 0; i < rates.length; i++) {
                ratio.put(ChessType.values()[i], rates[i]);
            }
            freeRatioForRoom.put(configRoom.getId(), RatioProbability.valueOf(ratio));
            Map<Integer, Map<Integer, Integer>> count2Rate = configRoom.getCount2Rate();
            for (ChessType type : ChessType.values()) {
                if (type.isSpecial() || type == CT_WILD) {
                    continue;
                }
                Map<Integer, Integer> temp = count2Rate.get(type.ordinal());
                temp.forEach((key, val) -> {
                    if (key <= type.limit || type.limit == 0) {
                        type.limit = key;
                    }
                    type.count2Rate.put(key, val);
                });
            }
        }

    }

    public int getLimit() {
        return limit;
    }

    public boolean contains(ChessType chess) {
        return all.contains(chess);
    }

    /**
     * @param roomId
     * @param ignore
     * @return
     */
    public static ChessType getChess(boolean free, int roomId, Collection<ChessType> ignore) {
        if (free) {
            return freeRatioForRoom.get(roomId).getResult(ignore);
        } else {
            return normalRatioForRoom.get(roomId).getResult(ignore);
        }
    }


    public int getRate(int count) {
        return count2Rate.get(count);
    }
}
